var CommonUtil = CommonUtil || {};

CommonUtil.getSystemVersion = function () {
    var systemVersion = '';
    if (!app.framework_version || window.nativeVersion < app.framework_version) {
        return systemVersion;
    }
    if (cc.sys.os === cc.sys.OS_IOS) {
        systemVersion = jsb.reflection.callStaticMethod('CommonUtil', 'getSystemVersion');
    } else if (cc.sys.os === cc.sys.OS_ANDROID) {
        systemVersion = jsb.reflection.callStaticMethod(packageUri + '/utils/CommonUtil', 'getSystemVersion', '()Ljava/lang/String;');
    }
    cc.log('手机系统版本号：' + systemVersion);
    return systemVersion;
};

CommonUtil.getSystemModel = function () {
    var deviceType = null;
    if (!app.framework_version || window.nativeVersion < app.framework_version) {
        return deviceType;
    }
    if (cc.sys.os === cc.sys.OS_IOS) {
        return jsb.reflection.callStaticMethod('CommonUtil', 'getSystemModel');
    } else if (cc.sys.os === cc.sys.OS_ANDROID) {
        deviceType = jsb.reflection.callStaticMethod(packageUri + '/utils/CommonUtil', 'getSystemModel', '()Ljava/lang/String;');
    }
    cc.log('手机设备型号：' + deviceType);
    return deviceType;
};

/**
 * 拉伸适配
 * @param node
 */
var setDesignResolution = function (node) {
    var size = cc.view.getFrameSize();
    //iPad不适配
    if (size.height / size.width > 0.56) {
        window.DesignSize = cc.winSize;
        return;
    }
    var frameSize = cc.director.getVisibleSize();
    if (gameData.AdaptationModel && gameData.AdaptationModel.indexOf(window.systemModel) >= 0) {
        frameSize = cc.size(1450, 720);
    }
    node.setContentSize(frameSize);
    window.DesignSize = frameSize;
    ccui.helper.doLayout(node);
};

/**
 * 公用方法
 * Created by zhangluxin on 16/8/4.
 */
/**
 * 判断是不是空字符串
 * @param {String} str
 * @returns {Boolean}
 */
var isNullString = function (str) {
    return !_.isString(str) || str == '' || str == 'null';
};
/**
 * 通过value寻找key
 * @param {Object} obj
 * @param {*} value
 * @returns {*}
 */
var findKey = function (obj, value) {
    var key = null;
    for (var id in obj) {
        if (obj.hasOwnProperty(id)) {
            if (obj[id] == value) {
                key = id;
            }
        }
    }
    return key;
};
/**
 * base64转换
 * @param base64
 * @return {ArrayBufferLike}
 */
var base64ToArrayBuffer = function (base64) {
    var binary_string = dcodeIO.ByteBuffer.atob(base64);
    var len = binary_string.length;
    var bytes = new Uint8Array(len);
    for (var i = 0; i < len; i++) {
        bytes[i] = binary_string.charCodeAt(i);
    }
    return bytes.buffer;
};

/**
 * 金币显示小数点后两位
 */
var equalNumDot2 = function (num) {
    var _num = num;
    if (num >= 10000 && num < 100000000) {
        num = num / 10000;
        _num = num.toFixed(2) + '万';
    } else if (num >= 100000000) {
        num = num / 100000000;
        _num = num.toFixed(2) + '亿';
    }
    return _num;
};

/** 毫秒转换友好的显示格式
 * 输出格式：21小时前
 * @param  {[type]} date [description]
 * @return {[type]}      [description]
 */
function timeStr(date) {
    //获取js 时间戳
    var time = new Date().getTime();
    //去掉 js 时间戳后三位，与php 时间戳保持一致
    time = parseInt((time - date * 1000) / 1000);

    //存储转换值
    var s;
    if (time < 60) {//小于1分钟
        return time + '秒前';
    } else if ((time < 60 * 60) && (time >= 60)) {
        //超过十分钟少于1小时
        s = Math.floor(time / 60);
        var second = time - s * 60;
        return s + '分钟' + second + '秒前';
    } else if ((time < 60 * 60 * 24) && (time >= 60 * 60)) {
        //超过1小时少于24小时
        s = Math.floor(time / 60 / 60);
        var minute = Math.floor(time / 60) - s * 60;
        return s + '小时' + minute + '分钟前';
    } else if (time >= 60 * 60 * 24) {
        //超过1天
        s = Math.floor(time / 60 / 60 / 24);
        var hour = Math.floor(time / 60 / 60) - s * 24;
        return s + '天' + hour + '小时前';
    } else {
        //超过3天
        var date = new Date(parseInt(date) * 1000);
        return date.getFullYear() + '/' + (date.getMonth() + 1) + '/' + date.getDate();
    }
};

/**
 * 轮询整个obj并且decode
 * @param obj
 */
var decodeObj = function (obj) {
    _.forIn(obj, function (value, key) {
        if (_.isObject(value)) {
            decodeObj(value);
        } else if (_.isString(value)) {
            obj[key] = decodeURIComponent(value);
        }
    });
};
/**
 * 截图
 * @param {cc.Node} node
 * @param {Function} callback
 * @public
 */
var captureNode = function (node, callback) {
    if (!cc.sys.isNative) {
        return;
    }
    var texture = new cc.RenderTexture(display.width, display.height, null, 0x88F0);
    texture.retain();
    texture.setAnchorPoint(0, 0);
    texture.begin();
    node.visit();
    texture.end();
    var time = timestamp2time(Math.round((new Date()).valueOf() / 1000));
    time = time.replace(/[\s:-]+/g, '_');
    var nameJPG = 'ss-' + time + '.jpg';

    PermissionUtil.requestPermission(PermissionType.storage_read);
    PermissionUtil.requestPermission(PermissionType.storage_write);
    texture.saveToFile(nameJPG, cc.IMAGE_FORMAT_JPEG, false, function () {
        texture.release();
        callback(jsb.fileUtils.getWritablePath() + nameJPG);
    });
};
/**
 * 複製節點
 * @param node
 * @param isCopyUserdata
 * @return {cc.Node}
 */
var duplicateNode = function (node, isCopyUserdata) {
    var cloneNode = null;
    // log('duplicateNode = '+node.getName());
    if (node instanceof cc.Sprite) {
        cloneNode = new cc.Sprite(node.getSpriteFrame());
        cloneNode.setBlendFunc(node.getBlendFunc());
        cloneNode.setFlippedX(node.isFlippedX());
        cloneNode.setFlippedY(node.isFlippedY());
    } else if (node instanceof ccui.ImageView) {
        var tmp = node.clone();
        tmp.removeAllChildren(true);
        cloneNode = tmp;
        // if (cc.sys.isNative) {
        //     var tmp = node.clone();
        //     tmp.removeAllChildren(true);
        //     cloneNode = tmp;
        // }
        // else {
        //     cloneNode = new ccui.ImageView(node['_textureFile']);
        //     cloneNode.setScale9Enabled(true);
        //     cloneNode.setContentSize(node.getContentSize());
        // }
    } else if (node instanceof ccui.CheckBox) {
        if (cc.sys.isNative)
            cloneNode = node.clone();
        else {
            cloneNode = new ccui.CheckBox();
            cloneNode._copySpecialProperties(node);
        }
    } else if (node instanceof ccui.Text) {
        cloneNode = new ccui.Text(node.getString(), node.getFontName(), node.getFontSize());
        var isCustom = node.getString().indexOf('\n') > 0;
        if (isCustom) {
            cloneNode.ignoreContentAdaptWithSize(node.isIgnoreContentAdaptWithSize());
        }
        cloneNode.setTextColor(node.getTextColor());
        cloneNode.setTextHorizontalAlignment(node.getTextHorizontalAlignment());
        cloneNode.setTextVerticalAlignment(node.getTextVerticalAlignment());
        if (cc.sys.isNative) {
            cloneNode.enableOutline(node.getEffectColor(), node.getOutlineSize());
            cloneNode.enableShadow(node.getShadowColor(), node.getShadowOffset(), node.getShadowBlurRadius());
        }
        // cloneNode = node.clone();
    } else if (node instanceof ccui.Slider) {
        cloneNode = node.clone();
    } else if (node instanceof ccui.LoadingBar) {
        var tmp = node.clone();
        tmp.removeAllChildren();
        cloneNode = tmp;
    } else if (node instanceof ccui.PageView) {
        var tmp = node.clone();
        tmp.removeAllPages();
        cloneNode = tmp;
    } else if (node instanceof ccui.ListView) {
        var tmp = node.clone();
        tmp.removeAllChildren();
        cloneNode = tmp;
    } else if (node instanceof ccui.ScrollView) {
        var tmp = node.clone();
        tmp.removeAllChildren();
        cloneNode = tmp;
    } else if (node instanceof ccui.Layout) {
        cloneNode = new ccui.Layout();
        cloneNode.setBackGroundColorType(node.getBackGroundColorType());
        cloneNode.setBackGroundColor(node.getBackGroundColor());
        cloneNode.setBackGroundColorOpacity(node.getBackGroundColorOpacity());
        cloneNode.setClippingEnabled(node.isClippingEnabled());
    } else if (node instanceof cc.ClippingNode) {
        cloneNode = new cc.ClippingNode();
        cloneNode.setStencil(node.getStencil());
        cloneNode.setAlphaThreshold(node.getAlphaThreshold());
        cloneNode.setInverted(node.isInverted());
    } else if (node instanceof ccui.TextBMFont) {
        var tmp = node.clone();
        tmp.removeAllChildren();
        cloneNode = tmp;
    } else if (node instanceof ccui.TextAtlas) {
        var tmp = node.clone();
        tmp.removeAllChildren();
        cloneNode = tmp;
    } else if (node instanceof ccui.TextField) {
        var tmp = node.clone();
        tmp.removeAllChildren();
        cloneNode = tmp;
        cloneNode.setPlaceHolder(node.getPlaceHolder());
    } else if (node instanceof cc.Node) {
        cloneNode = new cc.Node;
    }
    if (!node) {
        return null;
    }
    if (!cloneNode) {
        // console.log('克隆失败,节点名称:' + node.getName());
        http.uploadErrorFileToOSS('克隆失败,节点名称:' + node.getName());
        return null;
    }

    cloneNode.setScaleX(node.getScaleX());
    cloneNode.setScaleY(node.getScaleY());
    cloneNode.setVisible(node.isVisible());
    cloneNode.setColor(node.getColor());
    cloneNode.setSkewX(node.getSkewX());
    cloneNode.setSkewY(node.getSkewY());
    cloneNode.setOpacity(node.getOpacity());
    cloneNode.setPosition(node.getPosition());
    cloneNode.setAnchorPoint(node.getAnchorPoint());
    cloneNode.setContentSize(node.getContentSize());
    cloneNode.setLocalZOrder(node.getLocalZOrder());
    cloneNode.setName(node.getName());

    var childlist = node.getChildren();
    _.forIn(childlist, function (child) {
        var tmpChild = duplicateNode(child, isCopyUserdata);
        if (cloneNode instanceof ccui.PageView) {
            cloneNode.addPage(tmpChild);
            cloneNode[child.getName()] = tmpChild;
        } else {
            cloneNode.addChild(tmpChild);
            cloneNode[child.getName()] = tmpChild;
        }
    });

    if (isCopyUserdata)
        cloneNode.setUserData(_.clone(node.getUserData()));
    return cloneNode;
};

/**
 * 获取资源路径
 */
var getCCSFileNamePath = function (ccsFileName) {
    var names = ccsFileName.split('/');
    var idx = names.indexOf('res');
    var newNames = _.dropRight(names, names.length - idx - 1);
    var resPath = newNames.join('/') + '/';
    return resPath;
};
/**
 * 只有以"_"开头的变量才会被绑定，以"_"开头的变量的子节点都可以以"_a.b、_a.b.c"访问。
 * */
var loadFile = function (target, jsonFile) {
    cc.assert(target && jsonFile);
    //绑定jsonFile
    if (!jsonFile) {
        return;
    }
    var rootNode = ccs.load(jsonFile, getCCSFileNamePath(jsonFile));
    rootNode.node.x = cc.winSize.width / 2;
    rootNode.node.y = cc.winSize.height / 2;
    rootNode.node.setAnchorPoint(cc.p(0.5, 0.5));
    rootNode.node.ignoreAnchorPointForPosition(false);
    bindMembers(rootNode.node, target);
    if (!target.rootNode) {
        target.rootNode = rootNode.node;
        target.addChild(rootNode.node);
    } else {//同时加载多个工程在一个场景
        var parent = rootNode.node;
        var arr = [];
        var children = parent.getChildren();
        for (var i = 0; i < children.length; i++)
            arr.push(children[i]);
        for (var i = 0; i < arr.length; i++) {
            arr[i].retain();
            arr[i].removeFromParent(false);
            target.rootNode.addChild(arr[i]);
            arr[i].release();
        }
        rootNode.node = target.rootNode;
    }
    return rootNode.node;
};
/**
 * 递归对rootWidget下的子节点进行成员绑定
 * @param rootWidget
 * @param target
 * @private
 */
var bindMembers = function (rootWidget, target) {
    var children = rootWidget.getChildren();
    var memberPrefix = '_';
    children.forEach(function (widget) {
        var widgetName = widget.getName();
        widgetName = widgetName.trim();
        // 控件名存在，绑定到target上
        var prefix = widgetName.substr(0, memberPrefix.length);
        if (prefix === memberPrefix) {
            target[widgetName] = widget;
        }
        // 绑定子控件,可以实现: a._b._c._d 访问子控件
        if (!rootWidget[widgetName]) {
            rootWidget[widgetName] = widget;
        }
        // 如果还有子节点，递归进去
        if (widget.getChildrenCount()) {
            bindMembers(widget, target);
        }
    });
};
/**
 * 裁切头像
 * @param url
 * @param headBg
 */
var loadCircleConorToSprite = function (url, headBg) {
    loadHeadImage(url, headBg, true);
};
/**
 * 获得当前时间戳
 * @return {Number}
 */
var getCurTimeMillisecond = function () {
    return Math.round((new Date()).getTime());
};
/**
 * 获取时间戳(秒)
 * @return {Number}
 */
var getCurTimestamp = function () {
    return Math.round((new Date()).getTime() / 1000);
};
/**
 * 获取时间戳(毫秒)
 * @return {Number}
 */
var getCurTimestampMills = function () {
    return _.now();
};
/**
 * 时间戳转时间
 * @param timestamp
 * @param format
 * @return {*}
 */
var timestamp2time = function (timestamp, format) {
    format = format || 'yyyy-mm-dd HH:MM:ss';
    var date = new Date(parseInt(timestamp) * 1000);
    return dateFormat(date, format);
};
/**
 * 删除数组中的项
 * @param list
 * @param indexList
 */
var removeInArray = function (list, indexList) {
    if (list == null) return;
    indexList.sort(function (a, b) {
        return b - a;
    });

    for (var i = 0; i < indexList.length; i++) {
        list.splice(indexList[i], 1);
    }
};
/**
 * 判断两个数组是否相同
 * @param object1
 * @param object2
 * @return {boolean}
 */
var Equals = function (object1, object2) {
    for (var propName in object1) {
        if (object1.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
            return false;
        } else if (typeof object1[propName] != typeof object2[propName]) {
            //Different types => not equal
            return false;
        }
    }
    for (propName in object2) {
        if (object1.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
            return false;
        } else if (typeof object1[propName] != typeof object2[propName]) {
            return false;
        }
        if (!object1.hasOwnProperty(propName))
            continue;
        if (object1[propName] instanceof Array && object2[propName] instanceof Array) {
            if (!Equals(object1[propName], object2[propName]))
                return false;
        } else if (object1[propName] instanceof Object && object2[propName] instanceof Object) {
            if (!Equals(object1[propName], object2[propName]))
                return false;
        } else if (object1[propName] != object2[propName]) {
            return false;
        }
    }
    return true;
};
/**
 * 删除数组中的项
 * @param list
 * @param obj
 */
var removeObjArray = function (list, obj) {
    if (list == null) return;
    var pos = -1;
    for (var i = 0; i < list.length; i++) {
        if (list[i] == obj) {
            pos = i;
            break;
        }
    }
    if (pos >= 0) {
        list.splice(pos, 1);
    }
};
var isBitActive = function (value, index) {
    return (value & Math.pow(2, index)) != 0;
};
/**
 * 比较两个数字
 * @param {Number} a
 * @param {Number} b
 * @return {Number}
 */
var compareTwoNumbers = function (a, b) {
    return a - b;
};
/**
 * 字符串截取
 * @param {String} str
 * @param {Number} n
 * @return {String}
 */
var ellipsisStr = function (str, n) {
    if (str == null || str == undefined) {
        return '';
    }
    if (str.length > n)
        str = str.substr(0, n - 1) + '..';
    return str;
};
/**
 * 获取时间戳
 */
var getCurrentTimeMills = function () {
    var date = new Date();
    var yy = date.getYear();
    var MM = date.getMonth() + 1;
    var dd = date.getDay();
    var hh = date.getHours();
    var mm = date.getMinutes();
    var ss = date.getSeconds();
    var sss = date.getMilliseconds();
    return Date.UTC(yy, MM, dd, hh, mm, ss, sss);
};
/**
 * sprite设置frame
 * @param sprite
 * @param name
 * @param paiRes
 */
var setSpriteFrameByName = function (sprite, name, paiRes) {
    for (var i = 0; i < 30; i++) {
        var frame = cc.spriteFrameCache.getSpriteFrame(name);
        if (!frame && paiRes) {
            cc.spriteFrameCache.addSpriteFrames(paiRes);
        } else {
            sprite.setSpriteFrame(frame);
            return;
        }
    }
    if (!cc.sys.isNative) {
        cc.error('getSpriteFrame(' + name + ') == null');
    } else {
        showAlert('getSpriteFrame(' + name + ') == null');
    }
};
/**
 * 数字转换 例如1转①
 * @param txtstring 数字
 * @returns {string} 转换后的数字
 */
var ToDBC = function (txtstring) {
    var tmp = '';
    if (typeof txtstring != 'string') {
        txtstring = '' + txtstring;
    }
    for (var i = 0; i < txtstring.length; i++) {
        if (txtstring.charCodeAt(i) == 32) {
            tmp = tmp + String.fromCharCode(12288);
        }
        if (txtstring.charCodeAt(i) < 127) {
            tmp = tmp + String.fromCharCode(txtstring.charCodeAt(i) + 65248);
        }
    }
    return tmp;
};
/**
 * track id
 * @type {number}
 */
var track_idx = 0;
/**
 * 创建spine动画
 * @param {String} spJson 动画json文件路径(必须和atlas文件同路径同名)
 * @returns {sp.SkeletonAnimation}
 */
var createSpine = function (spJson) {
    var spAtlas = spJson.replace('.json', '.atlas');
    return new sp.SkeletonAnimation(spJson, spAtlas);
};
/**
 * 播放spine动画
 * @param {String} spJson spine json路径
 * @param {String} [animaName] 动画名字
 * @param {Boolean} [repeate] 是否循环
 * @param {Function} [cb] 完成回调
 * @returns {sp.SkeletonAnimation}
 */
var playSpine = function (spJson, animaName, repeate, cb) {
    // cc.log(spJson, animaName);
    animaName = animaName || 'animation';
    if (repeate == undefined) {
        repeate = true;
    }
    var sp = createSpine(spJson);
    if (!sp) {
        cc.error('spine 动画为空!!!');
        return null;
    }
    sp.setAnimation(0, animaName, repeate);
    if (cb) {
        sp.setCompleteListener(cb);
    }
    return sp;
};
/**
 * 播放ccs动画
 * @param {cc.Node} distNode 目标节点
 * @param {String} res 资源路径
 * @param {Number} [x] 坐标
 * @param {Number} [y] 坐标
 * @param {Boolean} [loop] 是否循环播放
 * @param {Function} [endCallback] 结束回调
 * @returns {cc.Node}
 */
var playAnimScene = function (distNode, res, x, y, loop, endCallback) {
    if (!distNode || !distNode.isValid()) {
        cc.error('播放ccs动画目标节点不存在');
        return null;
    }
    if (!res) {
        cc.error('播放ccs动画资源不存在');
        return null;
    }
    x = x || 0;
    y = y || 0;
    if (loop == undefined) {
        loop = true;
    }
    var cacheNode = distNode.getChildByName(res);
    if (!cacheNode) {
        var animScene = ccs.load(res, getCCSFileNamePath(res));
        cacheNode = animScene.node;
        if (!cacheNode) {
            cc.error('播放ccs动画资源创建失败!');
            return null;
        }
        cacheNode.setName(res);
        distNode.addChild(cacheNode);
        cacheNode.runAction(animScene.action);
        cacheNode.setPosition(x, y);
        var data = cacheNode.getUserData() || {};
        data.action = animScene.action;
        cacheNode.setUserData(data);
    }
    var userdata = cacheNode.getUserData();
    if (!userdata || !userdata.action) {
        cc.error('播放ccs动画资源userdata错误!');
        return null;
    }
    userdata.action.play('action', loop);
    if (endCallback) {
        userdata.action.setLastFrameCallFunc(endCallback);
    }
    return cacheNode;
};
/**
 * 播放扔色子动画
 * @param {cc.Sprite} sprite
 * @param {Number} k 点数
 * @param {Function} endCb 完成回调
 */
var playThrowDice = function (sprite, k, endCb) {
    cc.spriteFrameCache.addSpriteFrames(res.dice_plist);
    var animFrames = [];
    for (var i = 0; i < 4; i++) {
        var frame = cc.spriteFrameCache.getSpriteFrame('dice_Action_' + i + '.png');
        animFrames.push(frame);
    }
    var animation = new cc.Animation(animFrames, 0.04);
    var action = cc.animate(animation);
    sprite.runAction(cc.sequence(
        action.repeat(2),
        cc.callFunc(function () {
            setSpriteFrameByName(sprite, 'dice_' + k + '.png', res.dice_plist);
        }),
        cc.delayTime(0.4),
        cc.callFunc(function () {
            if (endCb)
                endCb();
        })
    ));
};
/**
 * 播放帧动画
 */
var playFrameAnim = function (plistFilePath, prefix, frameCnt, speed, isLoop, sprite, endCb) {
    playFrameAnim2(plistFilePath, prefix, 0, frameCnt, speed, isLoop, sprite, endCb);
};
/**
 * 播放帧动画
 */
var playFrameAnim2 = function (plistFilePath, prefix, beginFrame, frameCnt, speed, isLoop, sprite, endCb) {
    cc.spriteFrameCache.addSpriteFrames(plistFilePath);
    var animFrames = [];
    for (var i = beginFrame; i < beginFrame + frameCnt; i++) {
        var frame = cc.spriteFrameCache.getSpriteFrame(prefix + i + '.png');
        animFrames.push(frame);
    }
    var animation = new cc.Animation(animFrames, speed);
    var action = cc.animate(animation);
    sprite.stopAllActions();
    if (isLoop) {
        sprite.runAction(action.repeatForever());
    } else {
        sprite.runAction(cc.sequence(action, cc.callFunc(function () {
            if (endCb)
                endCb();
        })));
    }
};
/**
 * 转时分秒
 * @param second
 * @returns {string}
 */
var secondToTime = function (second) {
    second = parseInt(second);
    var hour = Math.floor(second / 3600);
    var minite = Math.floor((second - hour * 3600) / 60);
    var sec = second - hour * 3600 - minite * 60;

    hour = hour < 10 ? '0' + hour : hour;
    minite = minite < 10 ? '0' + minite : minite;
    sec = sec < 10 ? '0' + sec : sec;
    if (hour == '00') {
        return minite + ':' + sec;
    } else {
        return hour + ':' + minite + ':' + sec;
    }
};

// --------------------- 字符串加密 --------------------------
var getAesString = function (data, key, iv) {
    var k = CryptoJS.enc.Utf8.parse(key);
    var v = CryptoJS.enc.Utf8.parse(iv);
    var encrypted = CryptoJS.AES.encrypt(data, k,
        {
            iv: v,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        });
    return encrypted.toString();
};
var getDAesString = function (encrypted, key, iv) {
    var k = CryptoJS.enc.Utf8.parse(key);
    var v = CryptoJS.enc.Utf8.parse(iv);
    var decrypted = CryptoJS.AES.decrypt(encrypted, k,
        {
            iv: v,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        });
    return decrypted.toString(CryptoJS.enc.Utf8);
};
var aes_key = '81dbc64373d95edb';
var aes_iv = '81dbc64373d95edb';
var getAES = function (data) {
    return getAesString(data, aes_key, aes_iv);
};
var getDAes = function (data) {
    return getDAesString(data, aes_key, aes_iv);
};
// ----------------------------------------------------------
/**
 * 错误上报
 * @param src
 * @param content
 * @param json
 */
var alertError = function (src, content, json) {
    if (!content)
        return;

    // var subArr = SubUpdateUtil.getLocalVersion();
    // var sub = '';
    // if (subArr && gameData.subModule) {
    //     sub = subArr[gameData.subModule];
    //
    // }
    var versiontxt = window.curVersion;//+ '-' + sub;

    cc.sys.isObjectValid(cc.director.getRunningScene()) && cc.director.getRunningScene().scheduleOnce(function () {
        content = timestamp2time(getCurTimestamp()) + ', 抱歉, 程序出了点小问题, 请截屏反馈给客服, 谢谢! 错误日志:\n' +
            ('版本号：' + versiontxt + '    ') +
            ('玩家ID:' + gameData.uid + '\n') +
            ('操作平台:' + cc.sys.os + '    ') +
            ('设备型号' + CommonUtil.getSystemModel() + '    ' + '系统版本' + CommonUtil.getSystemVersion() + '\n') +
            (gameData.roomId ? '房间号: ' + gameData.roomId + ', 局数: ' + gameData.curRound + '\n' : '') +
            (json ? JSON.stringify(json) + '\n' : '') +
            ('src: ' + src + '\n') +
            (content.stack || '') + '\n' +
            (content.message || '') + '\n' +
            (typeof content === 'string' ? content : '');
        content = content.replace(/\/.*?app\//g, '');
        cc.log(content);
        http.uploadErrorFileToOSS(content);
        //if(!cc.sys.isNative){
        //    showAlert(content);
        //}
    }, 0);
};
/**
 * 刷新tableView
 * @param tableView
 */
var tableViewRefresh = function (tableView) {
    if (tableView != null) {
        var content = tableView.getContainer();
        var posy = content.getPositionY();
        tableView.reloadData();

        var viewSize = tableView.getViewSize();
        if (posy == viewSize.height)
            return;

        var baseY = 0;
        var size = content.getContentSize();
        if (size.height < viewSize.height) {
            baseY = viewSize.height - size.height;
        }
        if (posy > baseY) posy = baseY;

        var topY = viewSize.height - size.height;
        if (posy < topY) posy = topY;

        content.setPositionY(posy);
        tableView.scrollViewDidScroll(tableView);
    }
};

var tableViewXSetPosition = function (tableView, rowWidth, itemCount, toIndex, addOffset) {
    if (addOffset == null) addOffset = 0;
    if (toIndex > 0) toIndex = 0;

    var content = tableView.getContainer();
    var viewSize = tableView.getViewSize();

    var posx = toIndex * rowWidth;

    content.setPositionX(posx);
    tableView.scrollViewDidScroll(tableView);
};
/**
 * 按钮扫光
 * @param sprite
 * @param x
 * @param y
 * @param stencil
 * @param scalex
 * @param scaley
 */
var lightButton = function (sprite, x, y, stencil, scalex, scaley) {
    if (sprite && sprite instanceof cc.Sprite) {
        if (!stencil) {
            stencil = main_module_common_res.Btn_stencil_png;
        }
        var offx = x || 0;
        var offy = y || 0;
        var clip = new cc.ClippingNode();
        var gameTitle = new cc.Sprite(stencil);
        clip.setStencil(gameTitle);
        clip.setAlphaThreshold(0);
        clip.setContentSize(cc.size(gameTitle.getContentSize().width, gameTitle.getContentSize().height));
        var clipSize = clip.getContentSize();
        clip.setPosition(cc.p(sprite.getPositionX() + offx, sprite.getPositionY() + offy));
        clip.setScaleX(scalex || 1);
        clip.setScaleY(scaley || 1);

        var spark = new cc.Sprite(main_module_common_res.ButtonLight_png);
        spark.setPosition(cc.p(-clipSize.width / 2, 0));
        clip.addChild(spark, 2);
        spark.setScaleY(gameTitle.getContentSize().height / spark.getContentSize().height);
        sprite.getParent().addChild(clip, 4);

        var moveAction = cc.moveTo(2.6, cc.p(clipSize.width, 0));
        var moveBack = cc.moveTo(0, cc.p(-clipSize.width, 0));
        var seq = cc.sequence(moveAction, moveBack);
        var repreatAction = cc.repeatForever(seq);
        spark.runAction(repreatAction);
    }
};
/**
 * 转时分秒
 * @param second
 * @returns {string}
 */
var secondToTime =  function (second) {
    second = parseInt(second);
    var hour = Math.floor(second / 3600);
    var minite = Math.floor((second - hour * 3600 ) / 60);
    var sec = second - hour * 3600 - minite * 60;

    hour = hour < 10 ? '0' + hour : hour;
    minite = minite < 10 ? '0' + minite : minite;
    sec = sec < 10 ? '0' + sec : sec;
    if(hour == '00'){
        return minite + ':' + sec;
    }else {
        return hour + ':' + minite + ':' + sec;
    }
};
/**
 * 修复客户端
 */
var showXiuFuWindow = function () {
    window.exitBox = showMessageBox('修复游戏会强制结束游戏进程，玩家需要重新进入游戏进行更新，确定退出游戏吗?', function () {
        clearAllAssets();

        var subNames = _.values(app.sub_module);
        for (var i = 0; i < subNames.length; i++) {
            clearSubFiles(subNames[i]);
        }
        cc.director.end();
        crash();
        cc.director.popScene();
        cc.director.popScene();
        cc.director.purgeDirector();
    }, function () {
        window.exitBox = null;
    });
};
/**
 * 清理旧版本资源
 * @public
 */
var clearAllAssets = function () {
    if (jsb.fileUtils.isFileExist(window.writablePath + 'project.manifest')) {
        jsb.fileUtils.removeFile(window.writablePath + 'project.manifest');
    }
    if (jsb.fileUtils.isFileExist(window.writablePath + 'project.manifest.tmp')) {
        jsb.fileUtils.removeFile(window.writablePath + 'project.manifest.tmp');
    }
    if (jsb.fileUtils.isFileExist(window.writablePath + 'version.manifest')) {
        jsb.fileUtils.removeFile(window.writablePath + 'version.manifest');
    }
    if (jsb.fileUtils.isFileExist(window.writablePath + 'version.manifest.tmp')) {
        jsb.fileUtils.removeFile(window.writablePath + 'version.manifest.tmp');
    }
    if (jsb.fileUtils.isDirectoryExist(window.writablePath + 'res')) {
        jsb.fileUtils.removeDirectory(window.writablePath + 'res');
    }
    if (jsb.fileUtils.isDirectoryExist(window.writablePath + 'src')) {
        jsb.fileUtils.removeDirectory(window.writablePath + 'src');
    }
    if (jsb.fileUtils.isDirectoryExist(window.writablePath + 'modules')) {
        jsb.fileUtils.removeDirectory(window.writablePath + 'modules');
    }
    cc.sys.localStorage.setItem('save_native_version', '1.0.0');
};
/**
 * 删除旧文件
 */
var clearSubFiles = function (sub) {
    var manifestDirPath = cc.sys.writablePath + sub + '/';
    var modulePath = cc.sys.writablePath + sub + '/modules';
    var manifestFileName = 'sub-' + sub + '.manifest';
    var manifestFile = manifestDirPath + manifestFileName;
    var vTempFile = manifestDirPath + 'version.manifest.tmp';
    var vFile = manifestDirPath + 'version.manifest';
    var pTempFile = manifestDirPath + 'project.manifest.tmp';
    var pFile = manifestDirPath + 'project.manifest';
    if (!jsb.fileUtils.isDirectoryExist(manifestDirPath)) {
        jsb.fileUtils.createDirectory(manifestDirPath);
    }
    if (jsb.fileUtils.isFileExist(manifestFile)) {
        jsb.fileUtils.removeFile(manifestFile);
    }
    if (jsb.fileUtils.isFileExist(vTempFile)) {
        jsb.fileUtils.removeFile(vTempFile);
    }
    if (jsb.fileUtils.isFileExist(vFile)) {
        jsb.fileUtils.removeFile(vFile);
    }
    if (jsb.fileUtils.isFileExist(pTempFile)) {
        jsb.fileUtils.removeFile(pTempFile);
    }
    if (jsb.fileUtils.isFileExist(pFile)) {
        jsb.fileUtils.removeFile(pFile);
    }
    if (jsb.fileUtils.isDirectoryExist(modulePath)) {
        jsb.fileUtils.removeDirectory(modulePath);
    }

    revertSubVersion(sub);
};
/**
 * 还原sub版本
 * @param sub
 */
var revertSubVersion = function (sub) {
    var verjson = getLocalVersion();
    verjson[sub] = '1.0.0';
    cc.sys.localStorage.setItem('sub-version', JSON.stringify(verjson));
};
// /**
//  * 获取本地的version存档
//  */
// var getLocalVersion = function () {
//     var verItem = cc.sys.localStorage.getItem(app.appName + '-sub-version');
//     if (!verItem) {
//         verItem = createLocalVersion();
//     }
//     var verjson = {};
//     try {
//         verjson = JSON.parse(verItem);
//     } catch (e) {
//     }
//     return verjson;
// };
// /**
//  * 建立新的本地的version存档
//  */
// var createLocalVersion = function () {
//     var verjson = {};
//     _.forIn(SUB_MODULE, function (sub) {
//         verjson[sub] = '1.0.0';
//     });
//     return JSON.stringify(verjson);
// };

/**
 * 获取本地的version存档
 */
var getLocalVersion = function () {
    var verItem = cc.sys.localStorage.getItem('sub-version');
    if (!verItem) {
        // verItem = createLocalVersion();
        verItem = '{}';
    }
    var verjson = {};
    try {
        verjson = JSON.parse(verItem);
    } catch (e) {
    }
    return verjson;
};

/**
 * 建立新的本地的version存档
 */
var createLocalVersion = function () {
    var verjson = {};
    _.forIn(app.sub_module, function (sub) {
        verjson[sub] = '1.0.0';
    });
    return JSON.stringify(verjson);
};

/**
 * 崩溃
 */
var crash = function () {
    if (cc.sys.os === cc.sys.OS_IOS) {
        jsb.reflection.callStaticMethod('CommonUtil', 'crash');
    }
    cc.director.end();
};
/**
 * 深拷贝
 * @param source
 * @returns {Array}
 */
var deepCopy = function (source) {
    var result;
    if (_.isArray(source)) {
        result = [];
        for (var i = 0; i < source.length; i++)
            result.push(typeof source[i] === 'object' ? deepCopy(source[i]) : source[i]);
    } else {
        result = {};
        for (var key in source) {
            if (source.hasOwnProperty(key))
                result[key] = typeof source[key] === 'object' ? deepCopy(source[key]) : source[key];
        }
    }
    return result;
};

/**
 * 数组差异
 * @param arr1
 * @param arr2
 * @returns {Array|*}
 */
var compareArray = function (arr1, arr2) {
    cc.log(arr1, arr2);
    arr1 = deepCopy(arr1);
    arr2 = deepCopy(arr2);
    var arr = arr1.length <= arr2.length ? arr1 : arr2;
    var arr_result = arr2.length >= arr1.length ? arr2 : arr1;
    for (var i = 0; i < arr.length; i++) {
        var idx = arr_result.indexOf(arr[i]);
        if (idx >= 0) {
            arr_result.splice(idx, 1);
        }
    }
    return arr_result;
};

/**
 *
 * @param paiId
 * @returns {{l: number, r: number}}
 */
var getPaiLR = function (paiId) {
    var t = [1, 9, 10, 18, 19, 27];
    var a = 0, b = 0;
    for (var i = 0; i < t.length; i += 2) {
        var l = t[i];
        var r = t[i + 1];
        if (paiId >= l && paiId <= r) {
            a = l;
            b = r;
            break;
        }
    }
    return {l: a, r: b};
};
/**
 *
 * @param n
 * @returns {boolean}
 */
var largerThan0 = function (n) {
    return n > 0;
};
/**
 * 安全显示隐藏节点
 * @param {cc.Node} target
 * @param {Boolean} visible
 */
var safeVisible = function (target, visible) {
    if (target && cc.sys.isObjectValid(target) && target instanceof cc.Node) {
        target.setVisible(visible);
    }
};
/**
 * 安全显示节点
 * @param {cc.Node} target
 */
var safeShow = function (target) {
    safeVisible(target, true);
};
/**
 * 安全隐藏节点
 * @param {cc.Node} target
 */
var safeHide = function (target) {
    safeVisible(target, false);
};
/**
 * 安全设置String
 * @param {cc.Node} target
 * @param {String} content
 */
var safeString = function (target, content) {
    if (target && cc.sys.isObjectValid(target)) {
        target.setString(content);
    }
};

/**
 * 重写加载资源
 * @param res
 * @param target
 * @returns {cc.Node}
 */
var loadNodeCCSItem = function (res, target) {
    var Item = ccs.load(res, getCCSFileNamePath(res));
    if (target) {
        target.addChild(Item.node);
    }
    return Item.node;
};
/**
 * 带适配的
 * @param res
 * @param target
 * @returns {cc.Node}
 */
var loadNodeCCS = function (res, target, modalLayerOpacity) {
    var Item = loadNodeCCSItem(res, target);
    Item.setAnchorPoint(cc.p(0.5, 0.5));
    Item.x = cc.winSize.width / 2;
    Item.y = cc.winSize.height / 2;

    var size = Item.getContentSize();
    var modalLayer = new ccui.Layout();
    modalLayer.setBackGroundColorType(ccui.Layout.BG_COLOR_SOLID);
    modalLayer.setBackGroundColor(cc.color('#1A1A1A'));
    modalLayer.setSwallowTouches(true);
    modalLayer.setTouchEnabled(true);
    modalLayer.setName('modalLayer');
    modalLayer.setContentSize(cc.winSize);
    modalLayer.setAnchorPoint(cc.p(0.5, 0.5));
    modalLayer.x = size.width / 2;
    modalLayer.y = size.height / 2;
    modalLayer.ignoreAnchorPointForPosition(false);
    modalLayer.setBackGroundColorOpacity(Math.floor(255 * 0.6));
    modalLayer.setName('modalLayer');
    if (modalLayerOpacity != undefined) {
        modalLayer.setBackGroundColorOpacity(Math.floor(modalLayerOpacity));
    }
    Item.addChild(modalLayer, -1);
    return Item;
};
/**
 * 保存IP地址
 * @param ipLists
 * @returns {*}
 */
var saveIpLists = function (ipLists) {
    if (ipLists == undefined || ipLists.length == 0) {
        return;
    }
    var saveIpLists = [];
    for (var i in ipLists) {
        try {
            saveIpLists.push(getDAes(ipLists[i]));
        } catch (e) {
            // cc.log('IP 地址保存失败');
        }
    }
    for (var i = 0; i < saveIpLists.length; i++) {
        // cc.log("save IP i:" + i + "  IP:" + saveIpLists[i]);
    }
    cc.sys.localStorage.setItem('ipList', JSON.stringify(saveIpLists));
    return saveIpLists;
};

/**
 * 保存链接成功的IP地址
 * @param ip 成功的链接IP
 * @param time 成功的链接时间
 */
var saveSuccesIpLists = function (ip, time) {
    var SuccesIpLists = cc.sys.localStorage.getItem('SuccesIpLists');
    if (SuccesIpLists) {
        SuccesIpLists = JSON.parse(SuccesIpLists);
    } else {
        SuccesIpLists = [];
    }
    var isExist = false;
    for (var i = 0; i < SuccesIpLists.length; i++) {
        if (SuccesIpLists[i].ip == ip) {
            SuccesIpLists[i].time = time;
            isExist = true;
            break;
        }
    }
    if (!isExist) {
        var data = {};
        data.ip = ip;
        data.time = time;
        SuccesIpLists.push(data);
    }
    cc.log('saveSuccesIpLists == ' + JSON.stringify(SuccesIpLists));
    cc.sys.localStorage.setItem('SuccesIpLists', JSON.stringify(SuccesIpLists));
};

var clearSuccesIpLists = function (ip) {
    var SuccesIpLists = cc.sys.localStorage.getItem('SuccesIpLists');
    if (SuccesIpLists) {
        SuccesIpLists = JSON.parse(SuccesIpLists);
    } else {
        SuccesIpLists = [];
    }
    for (var i = 0; i < SuccesIpLists.length; i++) {
        if (SuccesIpLists[i].ip == ip) {
            SuccesIpLists.splice(i, 1);
            break;
        }
    }
    cc.log('clearSuccesIpLists == ' + JSON.stringify(SuccesIpLists));
    cc.sys.localStorage.setItem('SuccesIpLists', JSON.stringify(SuccesIpLists));
};


var getSuccesIpLists = function () {
    var SuccesIpLists = cc.sys.localStorage.getItem('SuccesIpLists');
    var Ips = [];
    if (SuccesIpLists) {
        cc.log('SuccesIpLists == ' + SuccesIpLists);
        var IpLists = JSON.parse(SuccesIpLists);
        if (cc.isArray(IpLists) && IpLists.length > 0) {
            IpLists.sort(function (a, b) {
                return a.time - b.time;
            });
            for (var i = 0; i < IpLists.length; i++) {
                Ips.push(IpLists[i].ip);
            }
            cc.log('getSuccesIpLists == ' + JSON.stringify(Ips));
            return Ips;
        }
    }
    return Ips;
};
/**
 * 定位距离是否过近
 * @returns {String}
 */
var measureDistance = function () {
    if (window.inReview || window.inBanShu) return false;
    var loc = [];
    var name = [];
    for (var i = 0; i < gameData.players.length; i++) {
        if (gameData.players[i].loc) {
            var playerLoc = gameData.players[i].loc.split(',');
            loc.push(playerLoc);
            name.push(gameData.players[i].nickname);
        }
    }
    for (var i = 0; i < loc.length - 1; i++) {
        for (var j = i + 1; j < loc.length; j++) {
            var distance = LocationUtil.getFlatternDistance(loc[i][1], loc[i][0], loc[j][1], loc[j][0]);
            if (distance < 200)
                return name[i] + '与' + name[j] + '距离过近（' + distance + '米）';
        }
    }
    return null;
};

/**
 * 清除代码、资源
 *
 * */
var clearApp = function () {

    clearAllAssets();

    cc.sys.localStorage.removeItem('wx_openid');
    cc.sys.localStorage.removeItem('xl_openid');
    cc.sys.localStorage.removeItem('lb_openid');
    gameData.hasLogined = false;
    network.disconnect();

    cc.sys.cleanScript('src/frameworks/FrameworkConfig.js');
    cc.sys.cleanScript('src/frameworks/FrameworkConfig.jsc');
    cc.sys.cleanScript('src/mainmodules/MainModuleConfig.js');
    cc.sys.cleanScript('src/mainmodules/MainModuleConfig.jsc');
    cc.sys.cleanScript('src/mainmodules/common/CommonConfig.js');
    cc.sys.cleanScript('src/mainmodules/common/CommonConfig.jsc');
    if (window.hasOwnProperty('framework_src')) {
        for (var i = 0; i < window.framework_src.length; i++) {
            cc.sys.cleanScript(window.framework_src[i]);
            cc.sys.cleanScript(window.framework_src[i] + 'c');
            // console.log('清除主模块代码【 ' + window.framework_src[i] + ' 】');
        }
        delete window['main_module_src'];
    }
    if (window.hasOwnProperty('main_module_common_src')) {
        for (var i = 0; i < window.main_module_common_src.length; i++) {
            cc.sys.cleanScript(window.main_module_common_src[i]);
            cc.sys.cleanScript(window.main_module_common_src[i] + 'c');
            // console.log('清除主模块代码【 ' + window.main_module_common_src[i] + ' 】');
        }
        delete window['main_module_common_src'];
    }
    if (window.hasOwnProperty('main_module_src')) {
        for (var i = 0; i < window.main_module_src.length; i++) {
            cc.sys.cleanScript(window.main_module_src[i]);
            cc.sys.cleanScript(window.main_module_src[i] + 'c');
            // console.log('清除主模块代码【 ' + window.main_module_src[i] + ' 】');
        }
        delete window['main_module_src'];
    }
    if (window.hasOwnProperty('privy_module_src')) {
        for (var j = 0; j < window.privy_module_src.length; j++) {
            cc.sys.cleanScript(window.privy_module_src[j]);
            cc.sys.cleanScript(window.privy_module_src[j] + 'c');
            // console.log('清除私有模块代码【 ' + window.privy_module_src[j] + ' 】');
        }
        delete window['privy_module_src'];
    }
    if (window.hasOwnProperty('privy_module_res')) {
        for (var k in window.privy_module_res) {
            cc.sys.cleanScript(window.privy_module_res[k]);
            cc.sys.cleanScript(window.privy_module_res[k] + 'c');
            // console.log('清除私有模块资源【 ' + window.privy_module_res[k] + ' 】');
        }
        delete window['privy_module_res'];
    }
};

var NoticeType = (function () {
    var t = [];
    t['wanfaDetails'] = 'wanfaDetails';
    t['clubInvite'] = 'clubInvite';
    t['quickJoin'] = 'quickJoin';
    t['createClub'] = 'createClub';
    t['freeSet'] = 'freeSet';
    return t;
})();


// var MessageType = (function () {
//     var t = [];
//     t['Refused'] = 'Refused';
//     t['Invite'] = 'Invite';
//     return t;
// })();

// 注意todo的两个点

var sctivityZhongqiu = function (callBack) {
    var signInUrl = null;
    if (gameData.opt_conf.zhongqiu == 1) {
        signInUrl = 'http://pay.yayayouxi.com/fyactivity/app/signIn';
    } else if (gameData.opt_conf.zhongqiu == 2) {
        signInUrl = 'http://pay.yayayouxi.com/fyactivity-test/app/signIn';
    }
    if (!signInUrl) {
        // console.log('服务 七夕活动未开启');
        return;
    }
    var data = {
        'playerId': gameData.uid,
        'area': app.area,
        'activityType': 36,
        'signKey': Crypto.MD5('feiyu-activity' + gameData.uid + app.area)
    };
    http.post(signInUrl, data,
        function (data) {
            // console.log(data);
            var nowDate = cc.sys.localStorage.getItem('Storage_zhongqiu') || ''; //一天只弹一次
            if (data.code == '0000' && nowDate != getMonthDay()) {
                cc.sys.localStorage.setItem('Storage_zhongqiu', getMonthDay());
                callBack();
            }
        }, function (data) {
            console.log(data); // callBack(false);
        });
};
var activityZhongqiu = function (area, roomid, time, maxuid) {
    if (!maxuid) {
        // console.log('大赢家uid 为空');
        return;
    }
    if (!area || !roomid) {
        // console.log('房间号 地区 能为空');
        return;
    }
    var boxUrl = null;
    if (gameData.opt_conf.zhongqiu == 1) {
        boxUrl = 'http://pay.yayayouxi.com/fyactivity/app/gameOverMessage';
    } else if (gameData.opt_conf.zhongqiu == 2) {
        boxUrl = 'http://pay.yayayouxi.com/fyactivity-test/app/gameOverMessage';
    }
    if (!boxUrl) {
        return;
    }
    /**
     * 2018-09-29 14:00:00  1538200800  活动时间
     * todo 活动过了，下次更新将此代码删掉
     * 时间段 在2018-09-29 14:00:00之前，并且我是大赢家;   客户端自己做判断显示（文案写的）
     * time 为总结算结束时间,
     * maxuid 为大赢家的uid
     */
    if (time <= 1538200800 && maxuid == gameData.uid) {
        // var zhongqiuReward = new ZhongqiuReward();
        // cc.director.getRunningScene().addChild(zhongqiuReward);
        showWindow('ZhongqiuRewardWindow');
    }
};

var getMonthDay = function () {
    var _date = new Date();
    var _mon = _date.getMonth() + 1;
    var _day = _date.getDate();
    return _mon + '_' + _day;
};
/**
 金币场金币显示
 */
var equalNum = function (num) {
    var _num = num;
    if (num >= 10000 && num < 100000000) {
        num = num / 10000;
        _num = num.toFixed(2) + '万';
    } else if (num >= 100000000) {
        num = num / 100000000;
        _num = num.toFixed(2) + '亿';
    }
    return _num;
};

var getNumString = function (num) {
    if (num) {
        if (num < 9999) {
            return num;
        } else if (num > 99999999) {
            return (Math.floor((num / 10000000)) / 10) + '亿';
        } else {
            return (Math.floor((num / 1000)) / 10) + '万';
        }
    }
};
/**
 客户端生成二维码
 */
var getErweima = function (erweima, url, cb) {
    QrcUtil.makeQrcode(erweima, url, null, cb);
};


var checkAllNodesValid = function (node) {
    if (!cc.sys.isObjectValid(node))
        return false;
    var children = node.getChildren();
    if (children.length) {
        for (var i = 0; i < children.length; i++)
            if (!checkAllNodesValid(children[i]))
                return false;
    }
    return true;
};

/**
 * 获取ccs对象缓存池
 * @private
 * @param  {String} fileName
 * @returns {{node: cc.Node, action: cc.Action}} ccsObj
 */
var getloadCCSCache = function (fileName) {
    window['view_ccs_cache'] = window['view_ccs_cache'] || [];
    var cahce = window['view_ccs_cache'];
    var ccsObj = null;
    _.forIn(cahce, function (obj) {
        if (obj.name == fileName) {
            ccsObj = obj.ccsObj;
        }
    });
    if(ccsObj && ccsObj.node.getParent()){
        ccsObj.node.removeFromParent(true);
    }
    if(ccsObj && ccsObj.node){
        ccsObj.node.setVisible(true);
    }
    return ccsObj;
};

/**
 * 重置ccs对象缓存池
 */
var refreshloadCCSCache = function (fileName) {
    window['view_ccs_cache'] = window['view_ccs_cache'] || [];
    var cahce = window['view_ccs_cache'];
    var ccsObj = null;
    var objData = null;
    _.forIn(cahce, function (obj) {
        if (obj.name == fileName) {
            objData = obj;
            ccsObj = obj.ccsObj;
        }
    });
    if(ccsObj){
        ccsObj.node.release();
    }

    var resPath = getCCSFileNamePath(fileName);
    ccsObj = ccs.load(fileName, resPath);
    ccsObj.node.setAnchorPoint(cc.p(0.5, 0.5));
    ccsObj.node.x = cc.winSize.width / 2;
    ccsObj.node.y = cc.winSize.height / 2;
    ccsObj.node.retain();
    objData.ccsObj = ccsObj;
}

var cacheCCS = function (res, distNode) {
    cc.log('cacheCCS start:' + getCurTimestamp());
    var mainscene = null;
    if (window.ccsCache && window.ccsCache[res]) {

    } else {
        mainscene = ccs.load(res, getCCSFileNamePath(res));
        mainscene.node.setAnchorPoint(cc.p(0.5, 0.5));
        mainscene.node.x = cc.winSize.width / 2;
        mainscene.node.y = cc.winSize.height / 2;

        window.ccsCache = window.ccsCache || {};
        window.ccsCache[res] = mainscene;
        mainscene.node.retain();
        distNode.addChild(mainscene.node);
    }
    cc.log('cacheCCS end:' + getCurTimestamp());
};


var loadCCSTo = function (res, distNode, rootName, moreArr) {
    moreArr = moreArr || [];
    var mainscene = null;
    if (window.ccsCache && window.ccsCache[res]) {
        mainscene = window.ccsCache[res];
        window.ccsCache[res] = null;
        distNode.addChild(mainscene.node);
        mainscene.node.release();
    }
    else {
        mainscene = ccs.load(res, getCCSFileNamePath(res));
        mainscene.node.setAnchorPoint(cc.p(0.5, 0.5));
        mainscene.node.x = cc.winSize.width / 2;
        mainscene.node.y = cc.winSize.height / 2;
        distNode.addChild(mainscene.node);
    }

    var interval = null;
    var checkFunc = function () {
        if (!checkAllNodesValid(distNode.getChildByName(rootName)))
            return;
        var rootNode = distNode.getChildByName(rootName);
        for (var i = 0; i < moreArr.length; i++) {
            var node = rootNode.getChildByName(moreArr[i]);
            if (!node || !cc.sys.isObjectValid(node))
                return;
        }
        clearInterval(interval);
        interval = null;

        var ret = true;
        if (distNode.getBeforeOnCCSLoadFinish && distNode.getBeforeOnCCSLoadFinish())
            ret = distNode.getBeforeOnCCSLoadFinish()();
        if (ret && distNode.onCCSLoadFinish) {
            distNode.onCCSLoadFinish.call(distNode);
        }
    };
    interval = setInterval(checkFunc, 1);
    checkFunc();
    return mainscene.node;
};

var addCachedCCSChildrenTo = function (res, distNode) {
    window.ccsCache = window.ccsCache || {};
    var isRelease = !!window.ccsCache[res];
    window.ccsCache[res] = window.ccsCache[res] || ccs.load(res, getCCSFileNamePath(res));
    var parent = window.ccsCache[res].node;
    var arr = [];
    for (var i = 0; i < parent.children.length; i++)
        arr.push(parent.children[i]);
    for (var i = 0; i < arr.length; i++) {
        arr[i].retain();
        arr[i].removeFromParent(false);
    }
    for (var i = 0; i < arr.length; i++) {
        distNode.getChildByName('Scene').addChild(arr[i]);
        arr[i].release();
    }
    if (isRelease)
        window.ccsCache[res].release();
    delete window.ccsCache[res];
};

var batchSetChildrenZorder = function (node, map) {
    for (var k in map)
        if (map.hasOwnProperty(k)) {
            var child = node.getChildByName(k);
            if (child)
                child.setLocalZOrder(map[k]);
        }
};

var getPositionRelativeToParent = function (node, level) {
    var t = node;
    var a = 0, b = 0;
    for (var i = 0; i < level; i++) {
        if (!t)
            return null;
        a += t.getPositionX();
        b += t.getPositionY();
        t = t.getParent();
    }
    if (t) {
        return cc.p(a, b);
    }
    return null;
};

var isSameColor = function (paiIdA, paiIdB) {
    if (paiIdA >= 1 && paiIdA <= 9)
        return paiIdB >= 1 && paiIdB <= 9;
    if (paiIdA >= 10 && paiIdA <= 18)
        return paiIdB >= 10 && paiIdB <= 18;
    if (paiIdA >= 19 && paiIdA <= 27)
        return paiIdB >= 19 && paiIdB <= 27;
    if (paiIdA >= 28 && paiIdA <= 34)
        return paiIdB >= 28 && paiIdB <= 34;
    return false;
};

var create$ = function (sceneNode) {
    var func = function (query, rootNode) {
        var arr = query.split(/\./g);
        var t = rootNode || sceneNode;
        for (var i = 0; i < arr.length; i++)
            if (t) {
                if (!cc.sys.isObjectValid(t)) {
                    // cc.log('-- not a valid object ' + query);
                    return null;
                }
                t = t.getChildByName(arr[i]);
            } else {
                return null;
            }
        return t;
    };
    var retFunc = null;
    if (_.isArray(sceneNode)) {
        retFunc = function (query, rootNode) {
            if (rootNode)
                return func(query, rootNode);
            else {
                for (var i = 0; i < sceneNode.length; i++) {
                    var ret = func(query, sceneNode[i]);
                    if (ret)
                        return ret;
                }
                return null;
            }
        };
    } else
        retFunc = func;
    return retFunc;
};


/**
 * 裁切头像
 * @param url
 * @param headBg
 */
var loadCircleConorToSprite = function (url, headBg) {
    loadHeadImage(url, headBg, true);
};
var loadImageToSprite = function (url, targetSprite, isclip) {
    if (isclip) {
        loadCircleConorToSprite(url, targetSprite);
    } else {
        // loadImageToSprite2(url, targetSprite);
        loadHeadImage(url, targetSprite, false);
    }
};

/**
 * 加载图片
 * @param {String} url 头像url
 * @param {cc.Sprite} stencil 裁切模板（如果是裁切，模板不能是透明图）
 * @param {Boolean} [is_clipping] 是否裁切，默认：false
 * */
var loadHeadImage = function (url, stencil, is_clipping) {
    if (!(stencil instanceof cc.Sprite)) {
        cc.error('传入的节点不是cc.Sprite类型');
        return false;
    }
    if (typeof url === 'undefined' || !url || url === '') {
        cc.error('头像url为空，加载默认头像！');
        url = res.defaultHead;
    }
    //聊呗 头像处理
    if (url.substr(0, 5) === 'https') {
        url = 'http' + url.substr(5, url.length - 5);
        if (url.charAt(url.length - 1) === '#') {
            url = url.substr(0, url.length - 1);
        }
    }
    if (typeof is_clipping === 'undefined' || !cc.sys.isNative) {
        is_clipping = false;
    }
    var origin_url = url;
    var md5_url = Crypto.MD5(url);
    // stencil['last_load_url'] = md5_url;
    var stencilSize = stencil.getContentSize();
    // var headSprite = stencil;
    var headSprite = null;

    if (is_clipping) {
        var clippingNode = stencil.getChildByName('ClippingNode');
        if (!clippingNode) {
            clippingNode = new cc.ClippingNode();
            clippingNode.attr({
                stencil: new cc.Sprite(stencil.getTexture()),
                x: stencilSize.width * 0.5,
                y: stencilSize.height * 0.5
            });
            clippingNode.setAlphaThreshold(0.5);
            clippingNode.setInverted(false);
            clippingNode.setName('ClippingNode');
            stencil.addChild(clippingNode, 1);
        }

        headSprite = clippingNode.getChildByName('headimage');
        if (!headSprite) {
            headSprite = new cc.Sprite(stencil.getTexture());
            clippingNode.addChild(headSprite);
            var headSize = headSprite.getContentSize();
            var scaleX = stencilSize.width / headSize.width;
            var scaleY = stencilSize.height / headSize.height;
            headSprite.setScaleX(scaleX);
            headSprite.setScaleY(scaleY);
        }
    } else {
        headSprite = stencil.getChildByName('headSprite');
        if (!headSprite) {
            headSprite = new cc.Sprite(stencil.getTexture());
            headSprite.x = stencilSize.width * 0.5;
            headSprite.y = stencilSize.height * 0.5;
            headSprite.setName('headSprite');
            stencil.addChild(headSprite, 1);
        }
    }

    var checkNumber = function (str) {
        var reg = /^[0-9]+.?[0-9]*$/;
        return reg.test(str);
    };

    var loadTexture = function (file_path, md5_url) {
        if (stencil['last_load_url'] && stencil['last_load_url'] === md5_url) {
            var texture = file_path;
            if (cc.sys.isNative && jsb.fileUtils.isFileExist(file_path)) {
                texture = cc.textureCache.addImage(file_path);
            }
            if (texture && cc.sys.isObjectValid(headSprite)) {
                headSprite.setTexture(texture);
                var headSize = headSprite.getContentSize();
                var scaleX = stencilSize.width / headSize.width;
                var scaleY = stencilSize.height / headSize.height;
                // if (!is_clipping) {
                //     scaleX = headSprite.getScaleX();
                //     scaleY = headSprite.getScaleY();
                // }
                headSprite.setScaleX(scaleX);
                headSprite.setScaleY(scaleY);
                //console.log('\n最后加载的头像 url = ' + origin_url);
            }
        } else {
            // console.log('\n不是最后加载的头像 url = ' + origin_url);
        }
    };

    var saveImage = function (data) {
        if (data) {
            var dir_path = jsb.fileUtils.getWritablePath() + 'headimage/';
            var file_path = dir_path + md5_url + '.jpg';
            if (!jsb.fileUtils.isDirectoryExist(dir_path)) {
                jsb.fileUtils.createDirectory(dir_path);
            }
            if (jsb.fileUtils.writeDataToFile(data, file_path)) {
                loadTexture(file_path, md5_url);
            } else {
                asyncDownloader();
                // console.log('Remote write file failed.');
            }
        } else {
            asyncDownloader();
            // console.log('Remote download file failed.');
        }
    };

    var asyncDownloader = function () {
        // console.log('cc.textureCache.addImageAsync下载远程头像：' + origin_url);
        cc.textureCache.addImageAsync(url, function (texture) {
            loadTexture(texture, md5_url);
        }, null);
    };

    var httpAsynDownloader = function () {
        var xhr = cc.loader.getXMLHttpRequest();
        xhr.responseType = 'arraybuffer';
        xhr.onreadystatechange = function () {
            // console.log('xhr.readyState: ' + xhr.readyState);
            // console.log('xhr.status:' + xhr.status);
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    saveImage(new Uint8Array(xhr.response));
                } else {
                    asyncDownloader();
                }
            }
        }.bind(this);
        xhr.open('GET', url, true);
        xhr.send();
    };

    var loadImageFile = function () {
        var url_arr = url.split('/');
        var suffix = url_arr[url_arr.length - 1];
        if (checkNumber(suffix)) {
            // console.log('old head url: ' + url);
            // 微信头像统一尺寸为：96 * 96
            url = url.substr(0, url.length - suffix.length) + '96';
            // console.log('new head url: ' + url);
        }
        // if (/wx.qlogo.*\/\d+/.test(url)) {
        //     url = url.substr(0, url.length - suffix.length) + '96';
        // }
        if (cc.sys.isNative) {
            var file_path = jsb.fileUtils.getWritablePath() + 'headimage/' + md5_url + '.jpg';
            if (jsb.fileUtils.isFileExist(file_path)) {
                // console.log('\n加载本地头像：' + origin_url);
                loadTexture(file_path, md5_url);
            } else {
                // console.log('\n下载远程头像：' + origin_url);
                httpAsynDownloader();
            }
        } else {
            asyncDownloader();
        }
    };

    stencil['last_load_url'] = Crypto.MD5(res.defaultHead);
    loadTexture(res.defaultHead, Crypto.MD5(res.defaultHead));
    if (url !== res.defaultHead) {
        stencil['last_load_url'] = md5_url;
        loadImageFile();
    }
};

/**
 * 通过mapId转换到sub子模块名称
 * @param map_id
 * @returns {*}
 */
var mapId2Sub = function (map_id) {
    var key = findKey(app.map_id, map_id);
    if (!key) {
        cc.error('mapId:' + map_id + ' 找不到对应的子模块');
        return;
    }
    return app.map_id_2_sub[key];
};

/**
 * 通过mapId转换得到玩法名称
 * @param map_id
 * @returns {*}
 */
var mapId2WanFa = function (map_id) {
    var key = findKey(app.map_id, map_id);
    if (!key) {
        cc.error('mapId:' + map_id + ' 找不到对应的玩法');
        return;
    }
    return app.map_id_2_wanfa[key];
};

/**
 * 通过mapid取名字
 * @param mapId
 * @public
 */
var mapId2Name = function (mapId) {
    var key = findKey(app.map_id, mapId);
    if (key) {
        return app.map_name[key];
    }
    //todo
    return this.appName;
};

var recoverColor = function (sprite) {
    sprite.setColor(cc.color(255, 255, 255));
};

var isIphoneX = function(){
    if(cc.winSize.width == 1560 && cc.sys.os == cc.sys.OS_IOS){
        return true;
    }
    return false;
};
window.Timer = {
    _start_timestamp: {},
    /**
     * 开始计时
     * @param {String} des
     * */
    start: function (des) {
        if (cc.isUndefined(des)) {
            return;
        }
        this._start_timestamp[des] = new Date().getTime();
    },

    /**
     * 结束计时
     * @param {String} des
     * */
    end: function (des) {
        if (cc.isUndefined(des) || !this._start_timestamp[des]) {
            return;
        }
        var end_timestamp = new Date().getTime();
        console.log('【' + des + '】耗时：' + (end_timestamp - this._start_timestamp[des]));
        delete this._start_timestamp[des];
    }
};